﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 商户收藏关注接口实现
    /// </summary>
    public class MerchantFavoriteService : BaseService, IMerchantFavoriteService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        public MerchantFavoriteService(IDbContextFactory contentFactory, IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<MerchantFavorite?> QueryAsync(Expression<Func<MerchantFavorite, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = await _context.Set<MerchantFavorite>()
                .Include(x => x.Merchant)
                .FirstOrDefaultAsync(funcWhere);
            return result;
        }

        /// <summary>
        /// 查询前几条数据
        /// </summary>
        public async Task<IEnumerable<MerchantFavorite>> QueryListAsync(int top, Expression<Func<MerchantFavorite, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<MerchantFavorite>()
                .Include(x => x.Merchant)
                .Where(funcWhere);
            result = result.OrderByBatch(orderBy);//调用Linq扩展类排序

            if (top > 0) result = result.Take(top);
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询分页列表
        /// </summary>
        public async Task<PaginationList<MerchantFavorite>> QueryPageAsync(int pageSize, int pageIndex, Expression<Func<MerchantFavorite, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = _context.Set<MerchantFavorite>()
                .Include(x => x.Merchant)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<MerchantFavorite>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 获取关注会员分页列表
        /// </summary>
        public async Task<PaginationList<MerchantFavoriteMemberDto>> QueryMemberPageAsync(int pageSize, int pageIndex,
            Expression<Func<MerchantFavoriteMemberDto, bool>> funcWhere, string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //联合查询重新组合
            var result = from f in _context.Set<MerchantFavorite>()
                         from m in _context.Set<Members>().Include(x => x.User).Where(m => m.UserId == f.UserId)
                         select (new MerchantFavoriteMemberDto
                         {
                             Id = f.Id,
                             UserId = f.UserId,
                             UserName = f.UserName,
                             MerchantId = f.MerchantId,
                             AddTime = f.AddTime,
                             Email = m.User != null ? m.User.Email : null,
                             Phone = m.User != null ? m.User.PhoneNumber : null,
                             Avatar = m.Avatar,
                             RealName = m.RealName,
                             Sex = m.Sex,
                             Birthday = m.Birthday
                         });
            result = result.Where(funcWhere);//加入查询条件
            result = LinqExtensions.OrderByBatch<MerchantFavoriteMemberDto>(result, orderBy);//调用Linq扩展类排序
            return await PaginationList<MerchantFavoriteMemberDto>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 添加一条记录
        /// </summary>
        public async Task<MerchantFavoriteDto> AddAsync(MerchantFavoriteEditDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //获取登录用户ID
            var userModel = await _userService.GetUserAsync();
            if (userModel == null)
            {
                throw new ResponseException("用户尚未登录");
            }
            //获取收藏记录，检查是否重复增加
            var favoriteModel = await _context.Set<MerchantFavorite>().FirstOrDefaultAsync(x => x.UserId == userModel.Id && x.MerchantId == modelDto.MerchantId);
            if (favoriteModel != null)
            {
                return _mapper.Map<MerchantFavoriteDto>(favoriteModel);
            }
            //获取商家信息
            var merchantModel = await _context.Set<Merchants>().FirstOrDefaultAsync(x => x.Id == modelDto.MerchantId);
            if (merchantModel == null)
            {
                throw new ResponseException($"商家[{modelDto.MerchantId}]不存在或已删除");
            }
            //映射成实体
            var model = _mapper.Map<MerchantFavorite>(modelDto);
            model.UserName = userModel.UserName;
            model.AddTime = DateTime.Now;
            //商家收藏总数加一，设置只修改一项
            merchantModel.FavoriteCount++;
            //保存
            _context.Set<Merchants>().Update(merchantModel);
            await _context.Set<MerchantFavorite>().AddAsync(model);
            var result = await this.SaveAsync();
            if (!result)
            {
                throw new ResponseException("添加收藏发生错误，请联系管理员");
            }
            //映射成DTO
            return _mapper.Map<MerchantFavoriteDto>(model);
        }

        /// <summary>
        /// 根据条件删除记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<MerchantFavorite, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead); //连接数据库

            var list = await _context.Set<MerchantFavorite>().Where(funcWhere).ToListAsync();
            if (list == null)
            {
                return false;
            }
            //循环查找商家
            List<Merchants> merchantList = new();
            foreach(var item in list)
            {
                var merchantModel = merchantList.FirstOrDefault(x => x.Id == item.MerchantId);
                if(merchantModel != null)
                {
                    merchantModel.FavoriteCount--;
                }
                else
                {
                    merchantModel = await _context.Set<Merchants>().FirstOrDefaultAsync(x => x.Id == item.MerchantId);
                    if (merchantModel != null)
                    {
                        merchantModel.FavoriteCount--;
                        merchantList.Add(merchantModel);
                    }
                }
            }
            _context.Set<MerchantFavorite>().RemoveRange(list);
            _context.Set<Merchants>().UpdateRange(merchantList);
            return await this.SaveAsync();
        }
    }
}